Writing a Game Engine – Pt. 2 – Messaging

This article follows from the Application Class article and assumes that you are familiar with that article.

Messaging is one of the most important subsystems in a game engine.  It allows the developer to decouple the occurrence of an event from the handling of that event.

Why Coupling Events with Event Handling is Bad

The design paradigm of responding to an event immediately can limit performance and cause the developer to write bad code.

Say you’re writing a stealth espionage game, let’s call it Plastic Gear Liquid.  The “Process Inputs” step might look conceptually like this:

  • Player presses the Shoot Gun button.
  • Game immediately triggers the character’s Shoot Gun action.

So far, so good.  But how would enemy responses work?

For example, when the main character (let’s call her Liquid Salamander) fires her gun, several things may need to happen. To name a few examples:

  • Animation System plays an animation of Liquid Salamander raising and firing her weapon.
  • Particle System causes a flash, and maybe some gun smoke, to be drawn.
  • Sound System plays an appropriate sound effect.
  • AI System alerts enemies to Liquid Salamander’s presence.

Without some kind of messaging in place, Plastic Gear Liquid would prove to be difficult to write.

Using messaging, the design is fairly straightforward:

  • During the application class’ “process user input” step:
    • Input Handler collects the user’s input (pressing the “shoot” button), and places a message on the message queue that the user pressed the shoot button.
  • During the “process commands” step:
    • Animation System looks at the “user pressed the shoot button” message and initiates Liquid Salamander’s shoot-weapon animation.
    • Particle System looks at the same message and begins the light flash/gun smoke particle effect.
    • Sound System looks at the same message and plays the appropriate sound effect.
    • AI System looks at the same message and initiates the notify-nearby-enemies routine (likely based on distance from the character and whatever other inputs).
  • During the “update actors” step:
    • Liquid Salamander’s animation advances.
    • The particle effects continue.
    • The sound effect keeps playing.
    • The AI enemies track down Liquid Salamander.

Implementing a Messaging Subsystem

There are probably many ways to implement messaging in a game.  The Falldown engine (and the WIP Gamma Engine) uses a message queue.  The message queue is, as the name suggests, a central queue of messages.  It is “central” because there is only one MessageQueue in the engine.  Any game objects (GameObjs) that participate in messaging will write to, and read from it.

The message queue interacts with Writers and Readers.  A Writer is any GameObj that leaves a message for any Reader; a Reader is any GameObj that reads messages left by any Writer.  Any GameObj can Reader, or a Writer, or both.

The key to the message queue is that messages are destinationless. Writers don’t know which specific Readers will receive their message, and similarly, Readers don’t know which Writers will leave messages of interest.  Instead, Writers publish their messages with a given Topic, and Readers subscribe to whatever Topics they’re interested in (this is called the publish/subscribe pattern).

An IRL Example

In Falldown, the message queue is implemented by a MessageQueue object.  The MessageQueue is an object that has the following:

  • a queue of Message objects
  • a collection of lists of registered Readers (in Falldown, I called them “RegisteredListeners”).

To register a listener, the MessageQueue object has a RegisterListener function that adds a specified listener to a list of listeners for a given topic.  The function looks something like this:

def RegisterListener(self, listener_name, listener, topic):
    self._registeredListeners[topic].append( { 'name': listener_name, 'ref': listener} )

The code snippet is a member function of the MessageQueue class. “_registeredListeners” is the container of lists of listeners for each message Topic..

NOTE: This function does not test for duplicate entries before adding/replacing items, but it is a good idea to do so in real life.

Once the listeners are registered, the rest of the messaging flow goes something like this:

  • During the “process inputs” step of the game loop:
    • The input handler collects keyboard presses and enqueues keypress event messages (e.g., Topic = ‘PlayerInput’) onto the MessageQueue object’s message queue.
      • Side note: To be clear, lower-case “message queue” is the concept we’re talking about; camel-case “MessageQueue” is the name of the object in the engine. The MessageQueue object contains a message queue, as well as other things.
  • During the “Process Commands” step of the game loop:
    • The MessageQueue dequeues a message off the queue, to be processed.
    • The MessageQueue then steps through the list of registered listeners for the message’s Topic.
    • For every RegisteredListener subscribed to the Topic:
      • The RegisteredListener “makes a note to self” to act on the contents of the Message. (Note that the RegisteredListener does not actually begin acting yet. That happens later.)
      • In Falldown, the Ball “makes a note to self” by setting state variables: “Moving Left = True/False”, or “Moving Right = True/False”
  • During the “Update” step:
    • The Actor processes its “notes to self” and acts
    • In Falldown, the Ball acts by actually changing its position to the left or right, depending on its state variables.

… And then after all that, we draw the scene (not pictured here)

About Message Objects

In Falldown, every Message contains:

  • A Topic, and
  • a Payload

The Topic is a string, e.g. “PlayerInput”.

The Payload is more complex.  In Falldown, the Payload contains:
* an Action, and
* Other Stuff, depending on the Action.

What constitutes “Other Stuff” depends on the programmer’s design.  It’s probably best to show a real example from Falldown:

message =
{
    'topic': 'PlayerControl'
,   'payload': {
                   'action': 'call_function'
               ,   'function_name': 'setLeftKeyPressedTrue'
               ,   'params' : ''
               }
}

In this example, the Payload contains:

  • an action, “call_function”
  • a function_name, “setLeftKeyPressedTrue”, which is the name of a function that sets a state variable for the ball.
  • params, a list of parameters to be sent into the function.

The Falldown engine uses the message above to compose a call to a function that does something useful.  For example, the above message will make the Ball call its own setLeftKeyPressedTrue() function.

In practice, you can design Messages to contain whatever Payload will be useful in your game. The design described in this article is meant to give you ideas to experiment with.

Happy gamedeving!

Writing a Game Engine – Pt. 1 – The Application Class

What is an Application Class?

The Application Class is a class that defines how the application will interact with the system it’s running on. It is the part of the engine that is responsible for interacting with hardware (input, display, sound, etc.) and other software components that make the system go.

A well-designed Application Class abstracts away the hardware and software interfaces so the game developer (i.e., the person using the engine to write a game) never has to know the particulars of, for example, taking input from a touch screen, or a keyboard, mouse, joystick, gamepad, microphone, VR wand, etc. Ideally, the engine developer (i.e. the person creating the engine) would want the input functions to be as simple as:

myInput = engine.getInput()

and automagically, the value of myInput would be something like KEYBOARD_KEY_SPACEBAR, or TOUCHSCREEN_TAP (maybe with some screen coordinates), or GAMEPAD_BUTTON_1..

Of course, in practice, it’s never quite that simple.  But the goal is to get close.

How Does One Make an Application Class?

Fundamentally, the Application Class for a game needs to do 3 things, and 3 things only:

  1. Collect inputs
  2. Process inputs/Crunch Data
  3. Output something

Of course, the details of those 3 steps can be immensely complex.  In the list above, “collect inputs” means to any gather input data which the game logic will use to compute stuff. “Inputs” can actually be user/game controller input, AI input, networking input, etc.

Similarly, the term, “process inputs,” is broad. For example, the game can process game controller input and turn it into commands (e.g. walk forward).

The controller input might lead to AI input, as mentioned above. For example, the user might press a gamepad button that causes the player to launch a homing missile at a target. In the same way that the controller generated an input that the game interpreted as a command to launch the missile, the missile itself, and the target, also generate input data that help the game calculate where the missile should go.

Lastly, “output something” entails drawing the scene, playing sound effects, vibrating the controller, etc. The outputs are feedback items that let the game player know what’s happening.

An IRL Example:

The Application class for Falldown x64, my entry for Low Rez Jam 2016 adds some complexity/structure to the 3-step model above:

  • Process user input
  • Process game commands
  • Update actors
  • Do pre-render stuff
  • Render the game scene
  • Do post-render stuff

In a bit more detail:

  • The “process user input” step involves collecting user input and translating it into game command messages.
  • The “process game commands” step involves consuming game command messages and executing the actions they instruct. In Falldown, game commands are things like “SetMovingLeftTrue” or “SetMovingLeftFalse”, for the ball.
  • The “update actors” step runs the game’s “simulation.” For example, the update step moves objects, performs collision detection, etc.
  • The “pre-render” step entails cleaning things up before drawing the scene. In Falldown, it involves constraining the ball to stay within the boundaries of the screen (after the “update actors” step already moved the ball based on gravity and user input).
  • The “render” step draws the game scene.
  • The “post-render step draws overlays, such as the score, level, etc. In a 2D game like Falldown, the game stats “overlay” doesn’t look like much. It makes more sense in a 3D game, where the overlay might be oriented relative to the “camera” looking into the virtual world.

Some notes:

  • Why is the “process input” step separated from the “process game command” step? The separation ensures that all game commands are executed when they’re supposed to be (more on this in the messaging article).
  • Why is there a pre-render, render, and post-render step? The short story is: I have read that breaking the scene rendering into those 3 stages is good practice, especially in more complex games.
  • Falldown uses Pygame (which is a Python wrapper around SDL) to interact with the computer’s hardware. Even though we are writing our own engine, we <strong>do not</strong> want to write our own low-level code.

Happy gamedeving!

Writing a Game Engine – Pt. 0 – Introduction

I’ve decided to try my hand at writing about writing a game engine.  The reason is: I’ve put a lot of time and energy into learning how to write a game from scratch, and I believe I can fill in gaps left by the materials I tried to learn from.

But, before I launch into discussing how to write a game engine (or maybe just to stall for time.. :-D), I’d like to talk to about what an engine is.

What Exactly Is A Game Engine?

To be honest, I’m not sure. Once upon a time, “game engine” used to refer to the guts of a game that made it think. In that sense, the a game engine was just a bunch of logic, math, and programming code. Nowadays, the term “game engine” has expanded to include entire toolkits.

The software kits known as “engines” have all sorts of goodies today that extend far beyond the old-school definition of “game engine,” including (but DEFINITELY not limited to):
* Graphical/node-based editors (tools that allow developers to create games without actually writing code)
* Wizards/helpers to compile the game to run on different platforms (e.g., web, mobile devices, computers, etc.)
* Scripting languages to abstract away computer science/programming details
* Art/graphic design tools
* … and also the ability to create the logic, math, and programming code that old-school “engine” refers to

That Sounds Intimidating; Where Do I Start?

The prospect of making all those tools sure does sound intimidating. That’s why I am only going to talk about the old-school “engine” parts: the programming code and math. (Truth be told; I have never tried to create visual tools or other sweet “new-school” engine parts. Maybe I’ll write about how to make those if I get around to it.)

This series of articles aims to shed some light on the development of Falldown x64. My handmade code is no Unity or Unreal Engine, but it taught me a few things about how those big-time engines might work under the hood. Because sharing is caring, and I care, I will share.

Some preface notes:

  • This article series is geared to be accessible to the near-absolute beginner, yet informative to intermediate/advanced developers.
  • I am relatively new at gamedev myself, so if any experts reading have comments, I’d love to get your input!
  • To any beginners reading this, know that any kind of computer programming, let alone game development, can be insanely difficult. You will feel like you have to learn 10 things at the same time, to accomplish 1 goal. (That feeling is completely valid and correct :-)). Hopefully these articles help with that.
  • This article series will be written using Python code samples because Falldown x64 was written in Python. But I hope to make the code sensible enough to be ported to any language.

Launchpad

  1. The Application Class
  2. Messaging
  3. Game States (the State Pattern) (Coming Soon!)

Free Source Code!!!!!

As I promised back whenever ago, I am making the source code to Falldown Low Rez available: https://github.com/masskonfuzion/falldown_low_rez

In some places, the code is straight-up ugly; in other places, it’s stubbed and not totally complete.  But in other places, I think the code is pretty slick, if I do say so myself.  Regardless of how it looks, it works!

Being a learning project, the emphasis is on the engine/code (I recognize that the aesthetic looks plain; I’ll make future projects look better).  To that end, the source code is open and free.  Of course, I’m happy to take donations 😉 If you’re feeling generous, you can Paypal me: masskonfuzion@masskonfuzion.com.

About the game, a few things have changed since I first submitted the game for the Low Rez Jam.  Now the game has:

  • A working UI/menus (using keyboard or mouse)
  • Customizable options
  • Somewhat of a difficulty curve
  • Keyboard input and game logic bug fixes

The UI stuff looks like this:

And the game looks like this:

In the video, you can see that the game moves faster than it did.  That was by choice.  Originally, I wanted the game to move in slow, staccato, single steps.  The difficulty would increase by reducing the amount of space between each row (i.e., adding more rows to the screen), as the player progressed through the game.  But during the jam, I ran into problems implementing that design. So instead, I reduced the amount of space between each row, and made the difficulty increase by slowly adding to the distance between gaps on consecutive rows.  That design choice required a faster-moving level.  Since the jam, I have had time to fix bugs, but I never returned to the slow-moving level design.

Stay tuned for more.  I can’t seem to put this project away, so I’m sure I’ll have another update.

Until next time!

Falldown x64 Post-Mortem

This is a discussion of my Falldown submission for Low Rez Jam 2016. Some vital stats on the game:

  • Programming Language: Python 2.7
  • Toolkit: Pygame (yes, the old, tried & true Pygame)
  • Editor: Vim
  • Platforms Supported: Windows, Linux

What Went Well

Finished Game

First and foremost, I finished a game! To boot, Low Rez Jam marked my first-ever game jam. Nevermind the fact that Falldown x64 is a rehash of a project I have done before. I still finished and released a game.

“Quantum Mechanics”

My favorite design feature is the concept of an “update delay”. The idea is: every object in the game is “eligible” to move only after waiting a certain amount of time. In other words, there is no concept of “velocity” in Falldown x64. Objects do not move a certain number of feet per second, or miles per hour, or any other “speed.” Instead, objects move exactly 1 space (i.e., 1 “quantum”), after a given time interval. So, a fast-moving object (like the ball) simply doesn’t have to wait as long to move as a slower-moving object (like the row of blocks the ball is rolling on).

That design greatly simplified collision detection. There is no “bullet/tunneling problem” in Falldown x64. Collisions are reliably handled with simple overlap tests.

Cool Score Splash Messages

I like how score updates turned out. Every time the ball passes through a gap, a score update pops up on the screen. That score update is driven by event-based messaging in the game engine. The game detects a collision between the ball and the  gap, and queues up a message for the Text Display Manager. The Text Display Manager processes the message and puts text on the screen.

Cross-Platform Support

Falldown x64 is cross-platform because Python and Pygame are cross-platform. I used cx_freeze to ‘compile’ the Python scripts into executable files.

I am only missing a Mac build. The reason is: cx_freeze can only produce executable files for the platform it runs on; it does not cross-compile (e.g., make a Windows executable from a Linux computer). But I don’t own a Mac. Does anyone want to donate a Mac I can use to create a Mac build? 🙂

What Went Not So Well

I should preface this section by saying: All things considered, my 1st game jam was a success. The points that follow describe what would have happened ideally. Having said that, the discussion of what went not-so-well can be summed up as, “I didn’t finish pretty much anything that makes a game a game.”

I went into the Low Rez Jam wanting to make a game with features:

  • a fun, challenging difficulty curve
  • retro 2D visual effects (maybe a particle system)
  • nostalgic retro sound effects & music
  • interesting gameplay elements (e.g., powerups, powerdowns, traps, etc.)

The game I made has none of that stuff. For starters, I began development almost a week after the jam started (even though I registered for the jam on time). I was not procrastinating; life happened. Once I did start, aside from a few days of “controlled burn,” I did not spend as much time developing the game as I could have under different circumstances. Still, I had ambitions to design good code, review it iteratively, tweak it, then add awesome gameplay features. Then, before I knew what happened, I would have a runaway hit that would pay my mortgage!

That didn’t happen. The reality was that I barely finished; I submitted the game less than 5 minutes before the deadline, and I was scrambling just to turn in a working program. I am happy that I finished, but I still learned a few lessons:

Start With Better Code Structure

I started off by prototyping a few things that I needed to work out in “draft” mode. At that time, I wasn’t concerned with my code design, so I did not organize my code as well as I could have. When the time came to begin development in earnest, I ended up simply continuing from my poorly laid-out “draft” mode code.

The code I wrote certainly worked, and it was rooted in knowledge I’ve gained from reading books and watching videos made by the experts. However, the structure of my code did not scale well. That left me scrambling to organize code mid-project when I could have been more productive in other areas. I know better, and I should have started off better.

Implement Messaging

I’m not talking about messaging as in Facebook Messenger; I’m talking about game subsystems messaging other subsystems.

A well-designed game (even my own Gamma Engine) enables systems to place messages in a central message queue, to be picked up by other systems. For example, with a message queue, a collision detection system can leave a message for the sound system, to trigger a sound effect when Thing A collides with Thing B. Using messaging in this way provides flexibility in handling various events that take place.

Unfortunately, I did not leave myself enough time to implement messaging the way I wanted to. As mentioned above, the score update and “Level Up” text displays do use messaging, but I should have incorporated messaging all across the board.

Include “Game Stuff”

A game should have non-playable, but still necessary, “game stuff.” Such stuff includes an introduction, main menu, setup options, in-game pause, credits, and any other elements that are expected in the software of a video game. I did write the game code with math to enable the game to be played full-screen, or in a window scaled from its original size. However, I didn’t have enough time to implement and test window resizing.

Add Sound and Effects

Of all the features I didn’t get to in trying to meet the Low Rez Jam submission deadline, sound is the most disappointing. I had ideas for audio that would have added retro ambience and flair to the game. Had I fully implemented messaging, adding sound would have been trivial.

Playtest

I didn’t playtest the game at all. As a result, the gameplay and difficulty curve are not balanced.

The lack of balance is directly caused by my not leaving enough time to add finishing touches. I wanted to program the difficulty so that, as the player progressed, the rows moved faster and also the spacing between each row decreased.

I was working on the difficulty curve on the last day of the jam, and I ran into some problems during my last-minute push to finish the game. As a result, I had to leave out the row spacing tweak. I also had to leave the gameplay largely unrefined.

Conclusion

Despite everything the game is missing, I am still proud that I accomplished my goal of finishing and releasing the project. Next goal: release a quality product 🙂

As for Falldown x64, I may decide to update the game to fill in the gaps, and I’m also pretty sure I’ll put the code on GitHub. And now that my feet are wet, stay tuned for more games!

Yay Graphics!

I figured out why my game was running so slowly!!  The solution was to install Bumblebee.

Not that Bumblebee

No, not that Bumblebee

The Bumblebee I installed is a software package that takes advantage of NVIDIA’s Optimus Technology.

Not that Optimus

No, not that Optimus

Optimus is NVIDIA’s proprietary, battery conserving, “hybrid” graphics technology. It optimizes battery life by switching between 2 video processing chips: (1) an all-purpose,  power-conservative chip, and (2) a dedicated, high-performance (and power-hungry) graphics chip. Optimus defaults to running programs on the all-purpose chip and disabling the high-performance chip. When higher graphics performance is needed, Optimus switches automatically to the high-performance chip.

Unfortunately, as far as I can tell, NVIDIA does not support Optimus on non-Windows operating systems (even my laptop’s BIOS setup screen said to enable Optimus only with Windows XP/7/8).

However, not to be defeated or excluded, smart Linux nerds created Bumblebee.

No!

No! Not that Bumblebee, either!

Bumblebee solves the performance issues with my game because it does not use the stock nvidia-libgl package. Instead, Bumblebee uses the mesa-libgl package that I described as running my game fast. Yet, it still enables fast 3D performance, using what appears to be a customized revision of the nvidia-libgl package. Bumblebee seems to address whatever issue  was in NVIDIA’s own GL library files that caused slow performance in my game.

The only (minor) drawback is that Bumblebee does not support automatic switching from the Intel chip to the NVIDIA chip. To use the NVIDIA, I have to prepend a specifier in front of the command for whatever program I want to run. For example, what used to be “playgame” is now “optirun playgame.” The “optirun” specifier causes Bumblebee to work its magic and use the high-performance chip.

All things considered, that is a miniscule issue, and I don’t mind manually controlling the graphics chips. It’s part of being a badass.

Mass KonFuzion out.

The Tribulations of a Linux Game Developer (Part 2)

This is part 2 of a long rant that should I have written in smaller, more frequent updates, over the past year or so. In part 1, I described the Linux laptop that is the subject of the rant you are about to experience. It is worth a read.

I have been using the aforementioned laptop for game development because I want to see how far I can push it. It is by no means a powerhouse; it has a modest Intel Core i7 at 2.4 GHz with 6 GB RAM and an NVIDIA Quadro NVS 4200M video chip. The main CPU can be clocked faster than 2.4 GHz, but then it runs disconcertingly hot. The graphics chip is meant for business, not games. Yet, I accept the modest specs because I am making a game with the simplest graphics possible.

Seriously, these are some basic graphics.

But now, I am encountering problems with my graphics rendering that I hadn’t noticed before, because until now, I hadn’t been concerned with graphics performance.

In troubleshooting, I found that, as usual, there are a number of different ways to get graphics working on Arch Linux with an NVIDIA graphics chip. Those links only point to the graphics drivers themselves. They do not relate to the graphics standards that software/games might be built with. In Linux, the options are, essentially, OpenGL (which has been around forever) and now Vulkan (which is new, circa Feb 2016).

If you looked at the content behind the links (though you weren’t expected to), you probably saw instructions to install mesa-libgl or nvidia-libgl, depending on which driver is installed. Those libgl packages contain different implementations of the OpenGL standard. mesa-libgl is open-source; nvidia-libgl is NVIDIA’s proprietary package.

Apparently, the two packages behave differently…

(As an aside, I mentioned before that my game engine is based on OpenGL. Therefore, now that Vulkan is here, I am technically using outdated technology. That is ok for now, because that outdated technology is well-established and well-supported.  The point is: Even though I am aware of Vulkan’s existence, I will focus on OpenGL for the purpose of this rant. One day in the future, I may write a different rant about Vulkan + Linux.)

My 2D game with runs smoothly with mesa-libgl, as it should, because the graphics are rectangles and circles. For reference, it looks like this:

However, with mesa-libgl, more fully-baked games (i.e., some Steam-powered games, and especially 3D games) run like a snail sliding on a molasses.

On the flipside, when I install nvidia-libgl, Steam games, other 3D games, and for that matter, other 2D games that aren’t mine, run perfectly.  But with nvidia-libgl, my game runs like a turtle climbing a mountain.

Here is a clip of the exact same game, running with nvidia-libgl installed, instead of mesa-libgl. Nothing else has changed, and the video is not doctored in any way:

I am not exactly sure what is causing the performance discrepancy. I will investigate it, figure it out, and report back.

Problems like this highlight my computer’s status as a bad game development machine. Every now and then, I have to spend an awful lot of time troubleshooting issues that are not related to the game itself. But, because I am a badass masochist, I wouldn’t have it any other way.

Mass KonFuzion out.

 

P.S. I hope this blog is detailed  enough for experts, but accessible to beginners. Basically, if my wife can follow along, I’ve done a good job. But if you think I’ve done a bad job, let me know in the comments.

The Tribulations of a Linux Game Developer (Part 1)

My computer is a terrible system for game development system, and I am foolish for using it. Let me explain…

I installed Arch Linux on my laptop.  I did that because I wanted to be a bad-ass. I wanted 100% control over every software application, every device driver, every bit of firmware.. Basically, I wanted to learn a metric ton of information, partly for myself, and partly so I could teach it to other people.

Basically, I'm trying to be this guy

In other words, I’m trying to be this guy

So far, my mission has been largely successful. I’ve essentially hand-built my system. In the process, I’ve learned just how many tiny components power a computer system, and how many of those components simply work on Windows PCs/Macs, right out of the box. The number is shocking. For that matter, even certain other Linux distros–Ubuntu et. al.–“just work”.

But as I said, I wanted to be a badass, and Arch is a Linux distro for badasses (i.e., masochists).  With Arch, if you didn’t explicitly install a thing, then that thing is not on your computer. That includes components you needed, but weren’t aware you needed, because those components come installed on most computers by the time they reach your hands… To describe a few concrete examples of what I am talking about:

  • By default, Arch is just a command line; it does not come with a windowing/GUI component. I chose exactly which desktop environment/window manager to use (XFCE4), which involved manually tweaking some config files and/or adding plugins to get the taskbar to look right, and to include things you’d expect to see, such as a clock, calendar, battery monitor, volume control, etc.
  • I installed Microsoft fonts because the default fonts in Arch look like actual crap. I also fought with font rendering to get the equivalent of ClearType in Windows. Without font smoothing, my display looked jagged and uneven.
  • I auditioned one sound system, and then another sound system, before figuring out exactly how the crap to set up the sound system to play audio from 2 or more programs at the same time. That’s not even an inherently useful activity (why would I need to listen to an MP3 at the same time as I’m watching a YouTube video?), but it’s something that other computers I’ve used just simply do.
  • I wrangled wireless drivers and firmware. Anyone who has configured wifi on a Linux computer knows the struggle.. Seriously, read the wiki. I mean, don’t read it, but just look at it..
  • I discovered that the default mouse driver didn’t work with my laptop’s touchpad, but it did work with track pointer thing. It turned out that installing a different driver worked perfectly.

I hope you haven’t been slow-reading each one of those links. But if you have been, you’ll notice that every problem encountered in Arch has at least 2 possible solutions. All of the possible solutions might work, with varying levels of compatibility with the rest of the computer’s software/hardware. As the system administrator, I have had to research the solutions and figure out which one would work best for my computer. The Arch Linux community is large and immensely helpful, but it also values self-sufficiency.

Again, I have learned a lot. But damn, Linux is annoying.

Basically, this...

Basically, this…

You may have noticed that this post did not talk much about game development. That is why you should read part 2!

 

Back Again!

While this video might give the impression that I’m back where I started, I have actually progressed a long way since my last post.  Falldown is coming along, and the engine I am working on supports many features, which I will get into after the video.  But first, feast your eyes:

What’s New?

The engine has a name: Gamma (or perhaps Gamma Engine).  The name is derived from “game” or “gamer.”  It is written in C++ and sports the following design/features:

  • Game Actors are containers for Actor Components.
    • Any object or character in the game can be an Actor.
    • Actor Components control the ways in which Actors behave/interact. For example:
      • Render Components enable Actors to be drawn (with or without texture mapping)
      • Input Components enable the user to control Actors using mouse/keyboard/etc.
      • Collision Components enable collision detection/response among Actors.
      • Physics Components enable different physics simulation methods, e.g. Euler, Verlet, RK4 to be used on Actors.
        • Different physics sims may be applied to different Actors at the same time. For example, a rocket may be simulated with Euler integration, while particles in the rocket’s smoke trail may use Verlet integration.
        • The user can define sims, such as constant-velocity (ignoring gravity/other forces).
  • An Actor Factory makes easy work of spawning Actors.
    • A Resource Loader parses Actor information from files, enabling Actors to be defined by templates.
  • An Application class encapsulates function calls necessary for the game to interact with the operating system.
    • An Event Queue class gathers events from the operating system and from game subsystems. The Event Queue is a base class for, e.g., Input Event Queue, Sound Event Queue, OS Event Queue, etc.
    • A Command Queue class translates system events into game commands.
  • A Game Logic class contains Actors, Event/Command Queues, and Event Handlers, such as a collision event handler.
  • A Game State class enables state transitions (e.g., the switch from the splash screen state to the playing state, in the video above, is a state transition).
    • Each Game State may contain a Game Logic object, which enables state-specific behavior, e.g., keyboard inputs being interpreted differently in State A than in State B.
    • The Game State class implements a stack-based game state management system. So, for example, a pause menu state can be stacked on top of a playing state.  When the user exits the pause menu, the playing state resumes.

Design Notes

  • Gamma is designed to be generic and scalable.
    • Previous iterations of Falldown (and their engines) took shortcuts that eventually led to my becoming stuck and unable to finish the projects.
  • The object classes in Gamma are designed polymorphically, to allow the developer to extend the engine to meet his or her needs.
  • The engine is cross-platform:
    • It primarily employs SDL (I plan one day to support DirectX)
    • It is compiled using gcc on Linux and mingw on Windows.  (I have not developed/tested on Mac, because I do not have a Mac.. yet).

Future development

To Falldown, I plan to add:

  • A proper game menu, with configurable options
  • Score keeping
  • “Scripted” levels (currently, levels are randomly generated)
  • 3D?
  • Multiplayer?

To Gamma, I plan to:

  • Add any updates necessary to build whatever Falldown features I think up.
  • Squash bugs.
  • Perhaps share on GitHub.

Thanks for reading, and stay tuned!

 

Shout-outs:

Thanks to Michael Kissner and his GamaSutra series on game engine development.  Gamma is based in part on his articles, which condense a lot of information from textbooks into easy-to-consume web articles.

Also, people like Chris DeLeon and his game development club/community keep me motivated when the going gets rough. (And it gets ROUGH sometimes…)

I also have to thank my wife, who puts up with me talking about programming computers all the time, coming to bed at 2 AM night after night. <3

There are many, many others out there — too many to list!

 

Still Cooking

Remember this?   Well, I’m still working on Falldown, but It’s been a while since my last post (over 8 months!!).  The reasons for the lag time are:

  1. My wife and I had a baby.  Well, she had the baby.  They’re both doing well, and they’re awesome, and we’re looking for a place to live; and
  2. I’m re-working the game engine for Falldown from the ground up.

On point 1, it’s awesome being a dad and a family man, but this blog is about the games! 😀

So, to be more specific on point 2, I have been writing a new game engine to power Falldown and also a few other simple game ideas I have in my back pocket.  I am basing the engine on the book: Game Coding Complete, 4th Edition (GCC4) and a host of other resources available around the web.

“But,” you ask, “Why are you writing Falldown again? You already had what looked like a working game!”

Well, I almost had a working game. However, I designed it poorly, and I reached a point where I would implement features sloppily, with notes “to be finished/improved later.” Each addition I made in that manner became more difficult to integrate into the game.  I decided to redesign some of the underlying engine, to make it more modular and scalable.

“But still,” you ask, “Why would you write your own game engine, when there are umpteen free, ready-made options available, from Unreal Engine to Unity to Cocos (2D and 3D) to Godot to xyz engine?”

The answer is: I simply want to.  I want to understand how to build and customize every piece of the game.  One day, I will use a professionally-developed engine.  Over the long term, I, as one nerd with a laptop, will likely not be able to keep pace with the quality of an engine developed and maintained by a team of dedicated people.  But, for now, from-scratch is the way to go.

I chose the GCC4 book because it presents a good mix of guidelines and tips/tricks, without giving away too many implementation details. (It so happens I am also using a different gcc, the GNU Compiler Collection for my development environment, but I digress…)

The book is a strange duality: It aims to teach good design practices and habits to beginner-level game development students, but it assumes the students are at least intermediate to advanced-level computer people.  To feel comfortable with writing a game engine based on GCC4, I had to learn quite a bit about programming in C++, and for that matter, math, physics, collision detection, artificial intelligence, sound, networking (ok, truth be told, I’m not so well-studied in the networking just yet, but I’ll get there).

Somehow, the duality works for me.  Once upon a time in undergrad, I studied computer engineering, so none of the game development subtopics intimidate me.  I was a bit surprised by how much I’ve forgotten over the years, and by how much I realized I never learned in school in the first place.

The process of getting back into it has been fun at times and frustrating at others.  But the frustration and confusion make the eventual epiphanies even more rewarding than they otherwise would have been.

There are more “complete” books about writing games or a game engine, but I like the GCC4 approach (i.e., the hard way).  That is what has delayed my blog updates.  But I will keep writing about the progress of the game, and I will also write some instructional posts on how to do things and stuff in game development.  Stay tuned!